//
//  MZAniDemoViewModel.m
//  MZAnimationDemo
//
//  Created by Chris Yang on 2016/11/30.
//  Copyright © 2016年 Chris Yang. All rights reserved.
//

#import "CAAnimation+MZCategory.h"

#import "MZAniDemoViewModel.h"

static NSString * const _aniDurationKey = @"MZAniTestDuration";

@interface MZAniDemoViewModel()

@end

@implementation MZAniDemoViewModel


- (id)init {
    
    self = [super init];
    
    if (self) {
        self.animationDuration = [[[NSUserDefaults standardUserDefaults] objectForKey:_aniDurationKey] floatValue];
    }
    
    return self;
}


#pragma mark - Animation Handlers

#pragma mark CAAnimation - Base

- (void)addTransferAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testTransAnimation"];
    
    layer.cornerRadius = rand() % 200;
    
    CAAnimation *tmpAni = [CAAnimation mzFadeTransitionWithDuration:_animationDuration];
    [layer addAnimation:tmpAni forKey:@"testTransAnimation"];
}

- (void)addPositionAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testPosAnimation"];
    
    CGPoint startPoint = [self layerCenter:layer];
    CGPoint endPoint = CGPointMake(rand() % 300 + 50, rand() % 300 + 50);
    
    CAAnimation *tmpAni = [CAAnimation mzMoveAnimationWithDuration:_animationDuration
                                                        startPoint:startPoint
                                                          endPoint:endPoint];
    [layer addAnimation:tmpAni forKey:@"testPosAnimation"];
}

- (void)addAlphaAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testAlphaAnimation"];
    
    float baseAlpha = layer.opacity;
    float tarAlpha = ((float)(rand() % 100) / 100.0);
    
    CAAnimation *tmpAni = [CAAnimation mzAlphaAnimationWithDuration:_animationDuration
                                                          baseAlpha:baseAlpha
                                                        targetAlpha:tarAlpha];
    [layer addAnimation:tmpAni forKey:@"testAlphaAnimation"];
}

- (void)addScaleAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testScaleAnimation"];
    
    float baseScale = layer.contentsScale;
    float tarScale = ((float)(rand() % 300) / 100.0);
    
    CAAnimation *tmpAni = [CAAnimation mzScaleAnimationWithDuration:_animationDuration
                                                          baseScale:baseScale
                                                        targetScale:tarScale];
    [layer addAnimation:tmpAni forKey:@"testScaleAnimation"];
}

- (void)addRotateAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testRotateAnimation"];
    
    float baseAngle = 0;
    float tarAngle = 2 * M_PI;
    
    CAAnimation *tmpAni = [CAAnimation mzRotateAnimationWithDuration:_animationDuration
                                                           baseAngle:baseAngle
                                                         targetAngle:tarAngle];
    [layer addAnimation:tmpAni forKey:@"testRotateAnimation"];
}

- (void)addGifAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testAnimationGif"];
    
    NSData *tmpData = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"test_nono" ofType:@"gif"]];
    
    CAAnimation *tmpAni = [CAAnimation mzGifAnimationWithGifData:tmpData duration:_animationDuration];
    [layer addAnimation:tmpAni forKey:@"testAnimationGif"];
}

#pragma mark CAAnimation - Senior

- (void)addTwinkleWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testTwinkleAnimation"];
    
    CAAnimation *tmpAni = [CAAnimation mzPlaneTwinkleAnimationWithDuration:_animationDuration];
    [layer addAnimation:tmpAni forKey:@"testTwinkleAnimation"];
}

- (void)addLineShakeAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testAnimationLineShake"];
    
    CGPoint startCenter = [self layerCenter:layer];
    CGPoint endCenter = startCenter;
    startCenter.x += (rand() % 400 - 200);
    startCenter.y += (rand() % 400 - 200);
    
    CAAnimation *tmpAni = [CAAnimation mzLineShakeAnimationWithDuration:_animationDuration
                                                             fromCenter:startCenter
                                                               toCenter:endCenter];
    [layer addAnimation:tmpAni forKey:@"testAnimationLineShake"];
}

- (void)addPlaneShakeAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testAnimationPlaneShake"];
    
    CGPoint layerCenter = [self layerCenter:layer];
    float scope = (rand() % 40);
    
    CAAnimation *tmpAni = [CAAnimation mzPlaneShakeAnimationWithDuration:_animationDuration
                                                             shakeCenter:layerCenter
                                                                   scope:scope];
    [layer addAnimation:tmpAni forKey:@"testAnimationPlaneShake"];
}

- (void)addExpandShrinkAniWithLayer:(CALayer *)layer {
    
    [layer removeAnimationForKey:@"testAnimationExpandShrink"];
    
    CAAnimation *tmpAni = [CAAnimation mzExpandShrinkAnimationWithDuration:_animationDuration];
    [layer addAnimation:tmpAni forKey:@"testAnimationExpandShrink"];
}

#pragma mark - Setter

- (void)setAnimationDuration:(float)animationDuration {
    
    _animationDuration = animationDuration;
    [[NSUserDefaults standardUserDefaults] setObject:@(animationDuration) forKey:_aniDurationKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    if ([_delegate respondsToSelector:@selector(viewModel:duraitonDidUpdate:)]) {
        [_delegate viewModel:self duraitonDidUpdate:_animationDuration];
    }
}

#pragma mark - MISC

- (CGPoint)layerCenter:(CALayer *)tmpLayer {
    
    CGPoint tmpPoint = CGPointMake(tmpLayer.frame.origin.x + tmpLayer.frame.size.width / 2,
                                   tmpLayer.frame.origin.y + tmpLayer.frame.size.height / 2);
    return tmpPoint;
}

#pragma mark - User Interface

- (void)addAnimationWithView:(UIView *)aniView aniTag:(MZAnimationTag)tag {
    
    CALayer *aniLayer = aniView.layer;
    
    if (MZAnimationTagTransfer == tag) {
        [self addTransferAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagPosition == tag) {
        [self addPositionAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagAlpha == tag) {
        [self addAlphaAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagScale == tag) {
        [self addScaleAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagRotate == tag) {
        [self addRotateAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagGIF == tag) {
        [self addGifAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagTwinkle == tag) {
        [self addTwinkleWithLayer:aniLayer];
        
    } else if (MZAnimationTagLineShake == tag) {
        [self addLineShakeAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagPlaneShake == tag) {
        [self addPlaneShakeAniWithLayer:aniLayer];
        
    } else if (MZAnimationTagExpandShrink == tag) {
        [self addExpandShrinkAniWithLayer:aniLayer];
        
    }
}


- (UIAlertController *)durationSettingActionSheet {
    
    NSArray *durationArray = @[
                               @(0.3f),
                               @(0.7f),
                               @(1.0f),
                               @(2.0f),
                               @(3.0f),
                               @(5.0f),
                               @(10.0f),
                               @(15.0f),
                               @(30.0f),
                               ];
    
    UIAlertController *tmpAc = [UIAlertController alertControllerWithTitle:@"设置动画时间"
                                                                   message:@"设定单次动画Demo的持续时间"
                                                            preferredStyle:UIAlertControllerStyleActionSheet];
    
    __weak MZAniDemoViewModel *weakSelf = self;
    for (NSNumber *tmpNum in durationArray) {
        
        NSString *tmpTitle = [NSString stringWithFormat:@"%.1f", tmpNum.floatValue];
        
        UIAlertAction *tmpAction = [UIAlertAction actionWithTitle:tmpTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [weakSelf setAnimationDuration:tmpNum.floatValue];
        }];
        
        [tmpAc addAction:tmpAction];
    }
    
    return tmpAc;
}

- (NSArray *)aniTitleArray {
    
    NSArray *titleArray = @[
                            @"渐变",
                            @"位置",
                            @"透明",
                            @"比例",
                            @"旋转",
                            @"GIF",
                            @"闪烁",
                            @"线抖",
                            @"面抖",
                            @"弹性",
                            ];
    
    return titleArray;
}

@end
